package me.flyray.crm.core.biz.customer;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import me.flyray.common.enums.*;
import me.flyray.common.exception.BusinessException;
import me.flyray.common.msg.BizResponseCode;
import me.flyray.common.msg.ResponseCode;
import me.flyray.common.util.CurrencyUtils;
import me.flyray.common.util.SnowFlake;
import me.flyray.crm.core.entity.*;
import me.flyray.crm.core.mapper.*;
import me.flyray.crm.facade.request.IntoAccountRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import me.flyray.common.util.EntityUtils;
import me.flyray.common.util.MD5;

import lombok.extern.slf4j.Slf4j;

/**
 * 入账相关的操作
 * modify by bolei
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CustomerIntoAccountBiz {

	@Value("${crm.account.balanceSaltValue}")
	private String balanceSaltValue;
	@Autowired
	private CustomerBaseMapper customerBaseMapper;
	@Autowired
	private MerchantAccountMapper merAccountMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	@Autowired
	private PersonalBaseMapper personalBaseMapper;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private PlatformAccoutConfigMapper platformAccoutConfigMapper;

	/**
	 * 个人或者商户入账相关的接口: 
	 * 若是商户账户： 
	 * 1、商户账号入账 
	 * 2、新增商户账户流水记录
	 * 若是个人账户： 
	 * 1、个人账户入账
	 * 2、新增个人账户流水记录
	 */
	public void intoAccount(IntoAccountRequest intoAccountRequest) {
		log.info("个人或者商户入账相关的接口 请求参数：{}" + EntityUtils.beanToMap(intoAccountRequest));
		//商户入账
		//查询客户信息中的商户号和个人编号
		CustomerBase customerBase = new CustomerBase();
		customerBase.setPlatformId(intoAccountRequest.getPlatformId());
		customerBase.setCustomerId(intoAccountRequest.getCustomerId());
		customerBase = customerBaseMapper.selectOne(customerBase);
		if (intoAccountRequest.getCustomerType().equals(CustomerType.CUST_MERCHANT.getCode())) {
			MerchantAccount queryAccount = new MerchantAccount();
			queryAccount.setPlatformId(intoAccountRequest.getPlatformId());
			queryAccount.setCustomerId(intoAccountRequest.getCustomerId());
			queryAccount.setMerchantId(customerBase.getMerchantId());
			queryAccount.setMerchantType(intoAccountRequest.getMerchantType());
			queryAccount.setAccountType(intoAccountRequest.getAccountType());
			MerchantAccount merchantAccount = merAccountMapper.selectOne(queryAccount);
			String accountId = "";
			// 商户账号还未开户
			if (null == merchantAccount) {
				//商户账号开通
				PlatformAccoutConfig queryaccoutConfig = new PlatformAccoutConfig();
				queryaccoutConfig.setPlatformId(intoAccountRequest.getPlatformId());
				queryaccoutConfig.setCustomerType(intoAccountRequest.getCustomerType());
				queryaccoutConfig.setAccountType(intoAccountRequest.getAccountType());
				PlatformAccoutConfig accoutConfig = platformAccoutConfigMapper.selectOne(queryaccoutConfig);
				//平台支持的账户类型不存在 就没法开户
				if (null == accoutConfig) {
					log.info("个人或者商户入账相关的接口-返回参数。。。。。。{}", intoAccountRequest);
					throw new BusinessException(ResponseCode.PLAT_ACC_TYPE_NOT_EXIST);
				}
				merchantAccount = new MerchantAccount();
				accountId = String.valueOf(SnowFlake.getId());
				merchantAccount.setCustomerId(intoAccountRequest.getCustomerId());
				merchantAccount.setAccountId(accountId);
				merchantAccount.setPlatformId(intoAccountRequest.getPlatformId());
				merchantAccount.setMerchantId(customerBase.getMerchantId());
				merchantAccount.setMerchantType(intoAccountRequest.getMerchantType());
				merchantAccount.setAccountType(intoAccountRequest.getAccountType());
				merchantAccount.setCcy("CNY");
				merchantAccount.setFreezeBalance(BigDecimal.ZERO);
				merchantAccount.setAccountBalance(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				DecimalFormat format = new DecimalFormat("0.00");
				String floatString = format.format(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				merchantAccount.setCheckSum(MD5.sign(floatString, balanceSaltValue, "utf-8"));
				merchantAccount.setStatus(AccountState.normal.getCode());
				merchantAccount.setCreateTime(new Date());
				merAccountMapper.insertSelective(merchantAccount);
				//如果交易类型是营收则往总交易账户增加交易金额
				if (TradeType.RECEIVE.getCode().equals(intoAccountRequest.getTradeType())){
					merchantAccount.setAccountType(AccountType.TX_TOTAL.getCode());
					merAccountMapper.insertSelective(merchantAccount);
				}
			}
			if (null != merchantAccount && AccountState.normal.getCode().equals(merchantAccount.getStatus())) {
				if (!MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())) {
					log.info("入账（第三方支付）返回参数。。。。。。{}", merchantAccount);
					throw new BusinessException(ResponseCode.PLAT_ACC_TYPE_NOT_EXIST);
				}
				merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getIntoAccAmt())));
				merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				merchantAccount.setUpdateTime(new Date());
				merAccountMapper.updateByPrimaryKeySelective(merchantAccount);
				//如果交易类型是消费或者营收则往总交易账户增加交易金额
				if (TradeType.PAYRECEIPT.getCode().equals(intoAccountRequest.getTradeType()) || TradeType.RECEIVE.getCode().equals(intoAccountRequest.getTradeType())){
					MerchantAccount totalAccount = new MerchantAccount();
					totalAccount.setPlatformId(intoAccountRequest.getPlatformId());
					totalAccount.setMerchantId(intoAccountRequest.getMerchantId());
					totalAccount.setMerchantType(intoAccountRequest.getMerchantType());
					totalAccount.setAccountType(AccountType.TX_TOTAL.getCode());
                    totalAccount = merAccountMapper.selectOne(totalAccount);
                    totalAccount.setAccountBalance(totalAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getIntoAccAmt())));
                    totalAccount.setCheckSum(MD5.sign(totalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
                    totalAccount.setUpdateTime(new Date());
					merAccountMapper.updateByPrimaryKeySelective(totalAccount);
				}
			}
			if (StringUtils.isEmpty(accountId)) {
				accountId = merchantAccount.getAccountId();
			}
			MerchantAccountJournal merAccountJournal = new MerchantAccountJournal();
			merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			merAccountJournal.setCustomerId(intoAccountRequest.getCustomerId());
			merAccountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			merAccountJournal.setMerchantId(intoAccountRequest.getMerchantId());
			merAccountJournal.setMerchantName(intoAccountRequest.getMerchantId());
			merAccountJournal.setFromAccount(intoAccountRequest.getFromAccount());
			merAccountJournal.setFromAccountName(intoAccountRequest.getFromAccountName());
			merAccountJournal.setToAccount(accountId);
			merAccountJournal.setToAccountName(intoAccountRequest.getAccountName());
			merAccountJournal.setAccountType(intoAccountRequest.getAccountType());
			merAccountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			merAccountJournal.setInOutFlag(InOutFlag.in.getCode());
			merAccountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
			merAccountJournal.setTradeType(intoAccountRequest.getTradeType());
			merAccountJournal.setCreateTime(new Date());
			merchantAccountJournalMapper.insertSelective(merAccountJournal);
		}

		//个人入账
		if (intoAccountRequest.getCustomerType().equals(CustomerType.CUST_PERSONAL.getCode())) {
			if ("05".equals(intoAccountRequest.getTradeType())) {
				//发表说说每天领取两次
				PersonalAccountJournal personalAccountJournalReq = new PersonalAccountJournal();
				personalAccountJournalReq.setPlatformId(intoAccountRequest.getPlatformId());
				personalAccountJournalReq.setPersonalId(intoAccountRequest.getPersonalId());
				Map<String, Object> jorunalReq = new HashMap<>();
				jorunalReq.put("platformId", intoAccountRequest.getPlatformId());
				jorunalReq.put("personalId", intoAccountRequest.getPersonalId());
				int revCount = personalAccountJournalMapper.queryPersonalAccountJournalCount(jorunalReq);
				log.info("个人或者商户入账相关的接口 发表说说领取原力值次数== " + revCount);
				if (revCount >= 2) {
					log.info("个人或者商户入账相关的接口 返回参数。。。。。。当天已经领取两次{}", BizResponseCode.REV_COUNT_OVER.getMessage());
					throw new BusinessException(ResponseCode.REV_COUNT_OVER);
				}
			}
			PersonalBase base = new PersonalBase();
			base.setPersonalId(intoAccountRequest.getPersonalId());
			PersonalBase reult = personalBaseMapper.selectOne(base);
			if (null == reult) {
				log.info("个人或者商户入账相关的接口 返回参数。。。。。。个人客户信息不存在");
				throw new BusinessException(ResponseCode.PER_NOTEXIST);
			}
			String perAccountId = "";
			PersonalAccount queryPerAccountparam = new PersonalAccount();
			queryPerAccountparam.setPlatformId(intoAccountRequest.getPlatformId());
			queryPerAccountparam.setPersonalId(intoAccountRequest.getPersonalId());
			queryPerAccountparam.setAccountType(intoAccountRequest.getAccountType());
			PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPerAccountparam);
			String accountType = null;
			if (null == personalAccount) {
				PlatformAccoutConfig queryaccoutConfig = new PlatformAccoutConfig();
				queryaccoutConfig.setPlatformId(intoAccountRequest.getPlatformId());
				queryaccoutConfig.setCustomerType(intoAccountRequest.getMerchantType());
				queryaccoutConfig.setAccountType(intoAccountRequest.getAccountType());
				PlatformAccoutConfig accoutConfig = platformAccoutConfigMapper.selectOne(queryaccoutConfig);
				//平台支持的账户类型不存在 就没法开户
				if (null == accoutConfig) {
					log.info("个人或者商户入账相关的接口-返回参数。。。。。。{}", queryPerAccountparam);
					throw new BusinessException(ResponseCode.PLAT_ACC_TYPE_NOT_EXIST);
				}
				personalAccount = new PersonalAccount();
				perAccountId = String.valueOf(SnowFlake.getId());
				personalAccount.setAccountId(perAccountId);
				personalAccount.setPlatformId(intoAccountRequest.getPlatformId());
				personalAccount.setPersonalId(intoAccountRequest.getPersonalId());
				personalAccount.setAccountType(intoAccountRequest.getAccountType());
				personalAccount.setCcy("CNY");
				personalAccount.setAccountBalance(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				DecimalFormat format = new DecimalFormat("0.00");
				String floatString = format.format(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				personalAccount.setCheckSum(MD5.sign(floatString, balanceSaltValue, "utf-8"));
				personalAccount.setFreezeBalance(BigDecimal.ZERO);
				personalAccount.setStatus(AccountState.normal.getCode());
				personalAccount.setCreateTime(new Date());
				personalAccountMapper.insertSelective(personalAccount);
			}
			if (null != personalAccount && AccountState.normal.getCode().equals(personalAccount.getStatus())) {
				if (!MD5.sign(CurrencyUtils.decimaltoString(personalAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())) {
					log.info("入账（第三方支付）返回参数。。。。。。{}", personalAccount);
					throw new BusinessException(ResponseCode.VERIFY_ACC_AMT);
				}
				personalAccount.setUpdateTime(new Date());
				personalAccount.setAccountBalance(personalAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getIntoAccAmt())));
				personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}
			if (StringUtils.isEmpty(perAccountId)) {
				perAccountId = personalAccount.getAccountId();
			}
			accountType = personalAccount.getAccountType();
			PersonalAccountJournal personalAccountJournal = new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(intoAccountRequest.getPersonalId());
			personalAccountJournal.setAccountId(perAccountId);
			personalAccountJournal.setAccountType(accountType);
			personalAccountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			//来往标志  1：来账   2：往账
			personalAccountJournal.setInOutFlag(InOutFlag.in.getCode());
			personalAccountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
			//交易类型（支付:01，退款:02，提现:03，充值:04, 发表说说领取：05, 分享领取: 06）
			personalAccountJournal.setTradeType(intoAccountRequest.getTradeType());
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
		}
	}

}
